<template>
  <el-select
    ref="saSelectTree"
    style="width: 100%;"
    clearable
    collapse-tags
    v-model="selTitle"
    :multiple="multiple"
    :placeholder="placeholder"
    :popper-class="popperClass"
    @remove-tag="handleSelectRemoveTag"
    @change="handleSelectChange"
    @clear="handleSelectClear"
  >
    <div class="sa-tree-search" v-if="showSearch">
      <el-input
        placeholder="请输入关键字"
        v-model="filterText"
        size="mini"
        clearable>
      </el-input>
    </div>
    <el-option
      :value="selOptValue"
      class="sa-select-option-item"
    >
      <div class="sa-select-tree-body">
        <el-tree
          id="tree-option"
          ref="optionTree"
          highlight-current
          :show-checkbox="showCheckbox"
          :data="treeData" 
          :props="treeProps"
          :node-key="nodeKey"
          :filter-node-method="filterTreeNode"
          @node-click="handleNodeClick"
          @check="handleTreeCheck">
        </el-tree>
      </div>
    </el-option>
  </el-select>
</template>

<script>
import { QG_QH_TREE_DATA } from '@/mock/tree-data'

const defaultProps = {
  nodeKey: 'code',
  children: 'children',
  label: 'name'
}

const defaultTreeData = [...QG_QH_TREE_DATA[0].children]

export default {
  name: 'SaTreeSelect',
  model: {
    prop: "defaultValue",
    event: "change"
  },
  props: {
    defaultValue: {
      type: [String, Number, Array]
    },
    // 清空
    clearable: {
      type: Boolean, default: true
    },
    // 树结构数据
    treeData: {
      type: [String, Array, Object],
      default: () => {
        return defaultTreeData
      }
    },
    // 树结构替换字段
    treeProps: {
      type: Object,
      default: () => {
        return defaultProps
      }
    },
    // 是否多选
    multiple: {
      type: Boolean, default: false
    },
    // 提示语
    placeholder: {
      type: String,
      default: '请选择'
    },
    // 是否展示搜索
    showSearch: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      // 下拉框选中数据
      selValue: '',
      // 下拉框选中数据
      selTitle: '',
      // 下拉框Option的值
      selOptValue: undefined,
      // 搜索关键字
      filterText: '',
    }
  },
  computed: {
    nodeKey () {
      const { treeProps: { nodeKey } } = this
      return nodeKey ? nodeKey : 'id'
    },
    showCheckbox () {
      return this.multiple
    },
    optionTree () {
      return this.$refs.optionTree
    },
    saSelectTreeRef () {
      return this.$refs.saSelectTree
    },
    popperClass () {
      let className = ['sa-tree-select-popper']
      if (this.showSearch) className.push('sa-tree-select-search')
      return className.join(' ').toString()
    }
  },
  watch: {
    defaultValue: {
      deep: true,
      immediate: true,
      handler (newValue, oldValue) {
        const { multiple } = this
        if (newValue) {
          this.$nextTick(() => {
            this.handleSetTreeNode(newValue)
            this.handleTreeExpandKeys(newValue)
          })
        } else {
          this.selValue = multiple ? [] : ''
          this.selTitle = multiple ? [] : ''
        }
      }
    },
    filterText(val) {
      this.optionTree.filter(val)
    }
  },
  methods: {
    // 下拉框值变化
    handleSelectChange(value) {
      // console.log("handleSelectChange")
    },
    // 多选下点击移除单个tag
    handleSelectRemoveTag(tag) {
      this.selValue.shift()
    },
    /** 点击清除select的清除按钮 */
    handleSelectClear () {
      const { multiple }  = this
      const value = multiple ? [] : ''
      this.selTitle = value
      this.selValue = value
      this.$emit('change', value, null)
    },
    /** 节点点击时 */
    handleNodeClick (node) {
      const { treeProps, multiple } = this
      if (multiple) return 
      if (node.children && node.children.length > 0) return
      console.log('handleNodeClick')
      this.selTitle = node[treeProps.label]
      this.selValue = node[treeProps.nodeKey]
      this.$emit('change', this.selValue, node)
      this.saSelectTreeRef.blur()
    },
    /** 复选框点击时 */
    handleTreeCheck (node, values) {
      console.log("checked", { node, values })
      const { treeProps } = this
      const { checkedKeys, checkedNodes } = values
      this.selValue = checkedKeys
      this.selTitle = checkedNodes.map(node => {
        return node[treeProps.label]
      })
      this.$emit('change', checkedKeys, checkedNodes)
    },
    /** 处理回显树数据回显 */
    handleSetTreeNode (value) {
      const { optionTree, treeProps } = this
      this.selValue = value
      if (isArray(value)) {
        this.selTitle = value.map(item => {
          const treeNode = optionTree.getNode(item)
          return treeNode.data[treeProps.label]
        })
      } else {
        const treeNode = optionTree.getNode(value)
        this.selTitle = treeNode.data[treeProps.label]
      }
    },
    /** 处理数据回显时下拉树展开 */
    handleTreeExpandKeys (value) {
      const { optionTree, multiple } = this
      if (isArray(value) && multiple) {
        optionTree.setCheckedKeys(value)
        value.forEach(item => {
          const treeNode = optionTree.getNode(item)
          if (treeNode && treeNode.parent) {
            this.setTreeExpandKeys(treeNode.parent)
          }
        })
      } else {
        optionTree.setCurrentKey(value)
        const treeNode = optionTree.getNode(value)
        if (treeNode && treeNode.parent) {
          this.setTreeExpandKeys(treeNode.parent)
        }
      }
    },
    /** 设置下拉树展开 */
    setTreeExpandKeys (node) {
      node.expanded = true
      if (node.parent) {
        this.setTreeExpandKeys(node.parent)
      }
    },
    /** 搜索树节点 */
    filterTreeNode (value, data) {
      if (!value) return true;
      const { treeProps: { label } } = this
      return data[label].indexOf(value) !== -1;
    }
  },
}
function isArray(arg) {
  if (typeof Array.isArray === 'undefined') {
    return Object.prototype.toString.call(arg) === '[object Array]'
  }
  return Array.isArray(arg)
}
</script>

<style lang="scss">
.sa-tree-select-search {
  .el-select-dropdown__list {
    padding: 0;
  }
}
.sa-tree-select-popper {
  .el-scrollbar {
    .el-select-dropdown__wrap {
      max-height: 365px !important;
    }
    .el-scrollbar__bar.is-vertical {
      z-index: 3;
    }
  }
  
}
</style>
<style lang="scss" scoped>
.sa-tree-search {
  position: sticky;
  top: 0;
  z-index: 2;
  display: block;
  padding: 6px;
  background: #fff;
}
.sa-select-option-item {
  background: #fff;
  overflow: scroll;
  height: 200px;
  overflow-x: hidden;
}
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
  height: auto;
  min-height: 200px;
  padding: 0;
  overflow: hidden;
}
</style>
